package org.dromara.system.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.dromara.common.core.enums.CommunityEnum;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.system.domain.vo.*;
import org.dromara.system.mapper.CommonMapper;
import org.dromara.system.service.ICommonService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;


@Service
public class CommonServiceImpl extends ServiceImpl<CommonMapper, CommonVo> implements ICommonService {
    private static final Logger log = LoggerFactory.getLogger(CommonServiceImpl.class);
    @Resource
    private CommonMapper commonMapper;

    @DS("#datasource")
    @Override
    public int getUserCount(String datasource) {
        return commonMapper.getUserCount(datasource);
    }

    @DS("#datasource")
    @Override
    public int getXqCount(String datasource) {
        return commonMapper.getXqCount(datasource);
    }

    @DS("#datasource")
    @Override
    public int getBuildingCount(String datasource) {
        return commonMapper.getBuildingCount(datasource);
    }

    @DS("#datasource")
    @Override
    public int getUnitCount(String datasource) {
        return commonMapper.getUnitCount(datasource);
    }

    //初始化小区统计数量、楼栋、单元、用户数量
    @Override
    public IndexTotalVo initCommunity() {
        IndexTotalVo vo = new IndexTotalVo();
        for (CommunityEnum communityEnum : CommunityEnum.values()) {
            int userNum = this.getUserCount(communityEnum.name());
            RedisUtils.setCacheObject("userCount" + communityEnum.name(), userNum);
            vo.setUserNum(vo.getUserNum() + userNum);
            int unitCount = this.getUnitCount(communityEnum.name());
            vo.setUnitNum(vo.getUnitNum() + unitCount);
            RedisUtils.setCacheObject("unitCount" + communityEnum.name(), unitCount);
            int xqCount = this.getXqCount(communityEnum.name());
            vo.setXqNum(vo.getXqNum() + xqCount);
            RedisUtils.setCacheObject("xqCount" + communityEnum.name(), xqCount);
            int buildingCount = this.getBuildingCount(communityEnum.name());
            vo.setBuildingNum(vo.getBuildingNum() + buildingCount);
            RedisUtils.setCacheObject("buildingCount" + communityEnum.name(), buildingCount);
        }
        RedisUtils.setCacheObject("communityTotal", vo);
        return vo;
    }

    @Override
    public Map<String, Integer> initZhiYuanStatistic() {
        Map<String, Integer> vo = new HashMap();
        for (CommunityEnum communityEnum : CommunityEnum.values()) {
            List<CommonVo> commonVos = this.getCountGroupByType(communityEnum.name());
            RedisUtils.setCacheObject("zhiyuan" + communityEnum.name(), commonVos);//每个数据源下的统计数量
            for (CommonVo commonVo : commonVos) {
                vo.put(commonVo.getZyTypeName(), vo.get(commonVo.getZyTypeName()) == null ? 0 : vo.get(commonVo.getZyTypeName()) + commonVo.getZyCount());
            }
        }
        RedisUtils.setCacheMap("ZhiYuanStatistic", vo); //所有的统计和
        return vo;
    }

    @DS("#datasource")
    private List<CommonVo> getCountGroupByType(String datasource){
        return commonMapper.getCountGroupByType(datasource);
    }
    @Override
    public List<ZhiYuanJiFenVo> getZhiYuanJiFen() {
        List<ZhiYuanJiFenVo> allList = new ArrayList<>();
        for (CommunityEnum communityEnum : CommunityEnum.values()) {
            List<ZhiYuanJiFenVo> jiFenVos = commonMapper.getZhiYuanJiFen(communityEnum.name());
            RedisUtils.setCacheObject("ZhiYuanJiFen" + communityEnum.name(), jiFenVos);//每个数据源下的统计数量
            allList.addAll(jiFenVos);
        }
        //重新排序  按照积分倒序排序，如果积分相同则按照昵称升序排序
        List<ZhiYuanJiFenVo> allListNew = allList.stream().sorted(Comparator.comparing(ZhiYuanJiFenVo::getUserIntegral, Comparator.nullsFirst(Comparator.naturalOrder())).reversed().thenComparing(ZhiYuanJiFenVo::getNickName)).collect(Collectors.toList());
        RedisUtils.setCacheObject("ZhiYuanJiFen", allListNew); //所有的统计和
        return allList;
    }

    @Override
    public Map<String, Integer> initFeedbackStatistic() {
        Map<String, Integer> vo = new HashMap();
        for (int i = 0; i < 13; i++) {
            if (i < 10) {
                vo.put("0" + i, 0);
            } else {
                vo.put(i + "", 0);
            }
        }
        for (CommunityEnum communityEnum : CommunityEnum.values()) {
            List<FeedbackVo> commonVos = commonMapper.getFeedbackCountGroupByMonth(communityEnum.name());
            RedisUtils.setCacheObject("FeedbackStatistic" + communityEnum.name(), commonVos);//每个数据源下的统计数量
            for (FeedbackVo commonVo : commonVos) {
                vo.put(commonVo.getMonthStr(), vo.get(commonVo.getMonthStr()) == null ? 0 : vo.get(commonVo.getMonthStr()) + commonVo.getNum());
            }
        }
        RedisUtils.setCacheMap("FeedbackStatistic", vo); //所有的统计和
        return vo;
    }

    /**
     * 1.获取用户活跃度统计 包含：活跃用户数、新增用户、注册志愿者、活跃志愿者  （这里的指标可以换一下，换成总用户数量，昨日新增用户，志愿者总数量，昨日志愿者注册数量；查询方法也通过初始化缓存以及定时任务方式实现）
     *
     * @return
     */
    @Override
    public Map<String, Integer> initUserStatistic() {
        Map<String, Integer> vo = new HashMap();
        vo.put("totalUserNum", 0);
        vo.put("yesterdayRegisterUserNum", 0);
        vo.put("yesterdayRegisterZyzNum", 0);
        vo.put("yesterdayActivityZyzNum", 0);
        for (CommunityEnum communityEnum : CommunityEnum.values()) {
            int totalUser = this.getUserCount(communityEnum.name());
            RedisUtils.setCacheObject("totalUserNum" + communityEnum.name(), totalUser);
            vo.put("totalUserNum", vo.get("totalUserNum") == null ? 0 : vo.get("totalUserNum") + totalUser);
            int registerUser = commonMapper.getRegisterUserCount(communityEnum.name());
            RedisUtils.setCacheObject("yesterdayRegisterUserNum" + communityEnum.name(), registerUser);
            vo.put("yesterdayRegisterUserNum", vo.get("yesterdayRegisterUserNum") == null ? 0 : vo.get("yesterdayRegisterUserNum") + registerUser);
            int registerZyz = commonMapper.getRegisterZyzCount(communityEnum.name());
            RedisUtils.setCacheObject("yesterdayRegisterZyzNum" + communityEnum.name(), registerZyz);
            vo.put("yesterdayRegisterZyzNum", vo.get("yesterdayRegisterZyzNum") == null ? 0 : vo.get("yesterdayRegisterZyzNum") + registerZyz);
            int activityZyz = commonMapper.getActivityZyzCount(communityEnum.name());
            RedisUtils.setCacheObject("yesterdayActivityZyzNum" + communityEnum.name(), activityZyz);
            vo.put("yesterdayActivityZyzNum", vo.get("yesterdayActivityZyzNum") == null ? 0 : vo.get("yesterdayActivityZyzNum") + activityZyz);
        }
        RedisUtils.setCacheMap("UserStatistic", vo);
        return vo;
    }

    /**
     * 获取民主议事全年每个月份 发布数量、 参数人数、 参与率、 参与率排名  （在初始化中先把所有库中的反馈数据统计按月份查出来。然后再取出来根据月份累加进行返回结果,其中参与率排名没法按月来吧，页面是个柱形图。无需排名也能看出来高低）
     *
     * @return
     */
    @Override
    public VoteVo initVoteStatistic() {
        VoteVo result = new VoteVo();
        Map<String, Integer> totalVo = new HashMap();
        Map<String, Integer> personVo = new HashMap();
        Map<String, Integer> participationRateVo = new HashMap();
        for (int i = 0; i < 13; i++) {
            if (i < 10) {
                totalVo.put("0" + i, 0);
                personVo.put("0" + i, 0);
            } else {
                totalVo.put(i + "", 0);
                personVo.put(i + "", 0);
            }
        }
        for (CommunityEnum communityEnum : CommunityEnum.values()) {
            List<VoteVo> totalVos = commonMapper.getVoteTotalGroupByMonth(communityEnum.name());
            RedisUtils.setCacheObject("VoteTotal" + communityEnum.name(), totalVos);//每个数据源下的统计数量
            for (VoteVo commonVo : totalVos) {
                if (totalVo.get(commonVo.getMonthStr()) == null) {
                    totalVo.put(commonVo.getMonthStr(), totalVo.get(commonVo.getMonthStr()) == null ? 0 : totalVo.get(commonVo.getMonthStr()) + commonVo.getTotal());
                }
            }
            List<VoteVo> personVos = commonMapper.getVotePersonTotalGroupByMonth(communityEnum.name());
            RedisUtils.setCacheObject("VotePersonTotal" + communityEnum.name(), personVos);//每个数据源下的统计数量
            for (VoteVo commonVo : personVos) {
                if (personVo.get(commonVo.getMonthStr()) == null) {
                    personVo.put(commonVo.getMonthStr(), personVo.get(commonVo.getMonthStr()) == null ? 0 : personVo.get(commonVo.getMonthStr()) + commonVo.getPersonNum());
                }
            }

        }
        for (int i = 0; i < 13; i++) {
            if (i < 10) {
                participationRateVo.put("0" + i, personVo.get("0" + i) / totalVo.get("0" + i) * 100);
            } else {
                participationRateVo.put("" + i, personVo.get("" + i) / totalVo.get("" + i) * 100);
            }
        }
        result.setTotalVo(totalVo);
        result.setPersonVo(personVo);
        result.setParticipationReteVo(participationRateVo);
        RedisUtils.setCacheObject("VoteStatistic", result); //所有的统计和
        return result;
    }

    //1.获取注册用户中 的实名认证和未实名认证的占比情况  （初始化+定时任务拉出基础数据）
    @Override
    public Map<String, Integer> initUserInfoStatistic() {
        Map<String, Integer> result = new HashMap();
        for (CommunityEnum communityEnum : CommunityEnum.values()) {
            int totalUser = this.getUserCount(communityEnum.name());
            RedisUtils.setCacheObject("totalUserNum" + communityEnum.name(), totalUser);
            result.put("totalUserNum", result.get("totalUserNum") == null ? 0 : result.get("totalUserNum") + totalUser);
            int rzUser = commonMapper.getIdCardInfoCount(communityEnum.name()); //此处查询只能根据身份证号是不是空来查询，因为实际业务中并没有校验身份证号是否标准正确。
            RedisUtils.setCacheObject("rzUser" + communityEnum.name(), rzUser);
            result.put("rzUser", result.get("rzUser") == null ? 0 : result.get("rzUser") + rzUser);
            int wrzUser = totalUser - rzUser;
            RedisUtils.setCacheObject("wrzUser" + communityEnum.name(), result.get("wrzUser") == null ? 0 : result.get("wrzUser") + wrzUser);
        }
        result.put("rzRate", (result.get("rzUser") == null ? 0 : result.get("rzUser")) / (result.get("totalUserNum") == null ? 0 : result.get("totalUserNum")) * 100);
        result.put("wrzRate", (result.get("wrzUser") == null ? 0 : result.get("wrzUser")) / (result.get("totalUserNum") == null ? 0 : result.get("totalUserNum")) * 100);
        RedisUtils.setCacheMap("UserInfoStatistic", result);
        return result;
    }

    ////todo 1.查询本社区的志愿者活动数量、参与人数、服务时间(服务时间去掉了，这个没法统计，统计没有意义)
    @DS("#datasource")
    @Override
    public Map getZhiyuanStatisticByDataSource(String datasource) {
        Map result = new HashMap();
        List<ZhiYuanStatisticVo> totalList = commonMapper.getZhiyuanStatisticByDataSource(datasource);
        result.put("activityNum", totalList);
        List<ZhiYuanStatisticVo> personNum = commonMapper.getZhiyuanPersonStatisticByDataSource(datasource);
        result.put("personNum", personNum);
        RedisUtils.setCacheMap("ZhiYuanStatisticByCommunityId" + datasource, result);
        return result;
    }


    @DS("#datasource")
    @Override
    public Map getZhiYuanRateStatisticByCommunityId(String datasource) {
        Map result = new HashMap();
        int total = commonMapper.getVoteRecruitNum(datasource);
        int cyrNum = commonMapper.getVoteCyrNum(datasource);
        result.put("cyrRateStr", cyrNum / total * 100 + "%");
        result.put("cyrRateNum", cyrNum / total * 100);
        RedisUtils.setCacheMap("ZhiYuanRateStatisticByCommunityId" + datasource, result);
        return result;
    }
    @DS("#datasource")
    @Override
    public List<ZhiYuanJiFenVo> getZhiYuanJiFenByCommunityId(String name) {
        List<ZhiYuanJiFenVo> jiFenVos = commonMapper.getZhiYuanJiFen(name);
        RedisUtils.setCacheObject("ZhiYuanJiFen" + name, jiFenVos);//每个数据源下的统计数量
        return jiFenVos;
    }

    @Override
    public List<FeedbackVo> getJiFenDuiHuanByCommunityId(String name) {
        List<FeedbackVo> jiFenVos = commonMapper.getJiFenDuiHuanByCommunityId(name);
        RedisUtils.setCacheObject("ZhiYuanJiFenDuiHuanCount" + name, jiFenVos);//每个数据源下的统计数量
        return jiFenVos;
    }

    @Override
    public List<FeedbackVo> getJiFenDuiHuanSumByCommunityId(String name) {
        List<FeedbackVo> jiFenVos = commonMapper.getJiFenDuiHuanSumByCommunityId(name);
        RedisUtils.setCacheObject("ZhiYuanJiFenDuiHuannum" + name, jiFenVos);//每个数据源下的统计数量
        return jiFenVos;
    }

    @Override
    public int getFeedbackRateByCommunityId(String name) {
        int total=commonMapper.selectTotalFeedback(name);
        int ycl=commonMapper.selectYclFeedback(name);
        return ycl/total;
    }

}

